﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using TangoGames.Base;
using TangoGames.Scene;
using incubation_xna3d.Config;
using incubation_xna3d.Scene;
using incubation_xna3d.HUD;
using incubation_xna3d.Enemies;
using TangoGames.Primitives3D;

namespace incubation_xna3d.Screens
{
    class GameScreen: Screen
    {
        #region Fields
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;

            //Hud
            public Hud hud;
            Texture2D ponteiro;
            Vector2 ponteiroposition;

            //Camera
            BasicCamera camera;

            //camera control
            CameraControl cameraControl;

            //Tabuleiro
            PathMap pathMap;

            //Controle da Cena
            ISceneManager sceneControl;

            //Serviço de entrada
            IInputService input;
            IDefaults defaults;
            IScreenManager screenManager;

            //objeto Sky
            Sky sky;

            //Soldado
            Soldier soldier;

            EnemiesManager e;
            
            /// <summary>
            /// Controle de final de jogo
            /// </summary>
            private bool endGame = false;

        #endregion

        #region Properties

            /// <summary>
            /// Controle de final de jogo
            /// </summary>
            public bool EndGame { get { return endGame; } set { endGame = value; } } 

        #endregion


        public GameScreen(Game game):base(game)
        {
            Init();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            //obj = new GameObject3D(this, camera, Content.Load<Model>("Models/map_game"));
            //obj.Position = new Vector3(0, 0, -150);
            //obj.Scale = 2.0f;


            //soldier.Scale = f;

            // soldier2 = new AnimedGameObject3D(this, camera, Content.Load<Model>("Models/Teste/dude"));
            // soldier2.Position = new Vector3(15.0f, 0.5f, -150.0f);
            //soldier2.Scale = 0.05f;

            //soldier3 = new AnimedGameObject3D(this, camera, Content.Load<Model>("Models/Teste/75_08"));
            //soldier3.Position = new Vector3(30.0f, 0.5f, -150.0f);
            //soldier3.Scale = 0.5f;

            // Adiciona o soldado à lista de elementos do turno
            //turn.addElement(soldier);

            // Agora é a vez do jogador
            //turn.UserTurn = true;
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            cameraControl.Update(gameTime);

            camera.Update(gameTime);

            base.Update(gameTime);

            hud.Update();
            ponteiroposition.X = input.mouse.X;
            ponteiroposition.Y = input.mouse.Y;

            if (soldier.Health <= 0) endGame = true;

        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Draw(GameTime gameTime)
        {
            //GraphicsDevice.RasterizerState = myRasterizerStateUnCulled;
            //GraphicsDevice.RasterizerState = myRasterizerStateWired;

            base.Draw(gameTime);

            //pathMap.DrawDebugSquares(this, camera,e.path);

            // Desenhar todos os objetos 2d
            spriteBatch.Begin();

            hud.Draw(spriteBatch);
            spriteBatch.Draw(ponteiro, ponteiroposition, Color.White);

            spriteBatch.End();

            RasterizerState myRasterizerStateNormal = new RasterizerState();
            myRasterizerStateNormal.FillMode = FillMode.Solid;//padrão
            myRasterizerStateNormal.CullMode = CullMode.CullCounterClockwiseFace;//padrão
            //-------------------------------------------------------------------------------------------------
            //Este comandos devem ser usados sempre todo frame pois o uso do SpriteBath altera estes parametros
            GraphicsDevice.RasterizerState = myRasterizerStateNormal;
            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
            //--------------------------------------------------------------------------------------------------

        }

        #region metodos privados da classe
        /// <summary>
        /// Inicializa jogo
        /// </summary>
        private void Init()
        {
            //Cria controle da cena
            sceneControl = new SceneManager(Game);

            // pegar os serviços
            input = (IInputService)Game.Services.GetService(typeof(IInputService));
            defaults = (IDefaults)Game.Services.GetService(typeof(IDefaults));
            screenManager = (IScreenManager)Game.Services.GetService(typeof(IScreenManager));

            // Cria a Hud
            hud = new Hud(Game.Content, Game.Window, Game.Services, sceneControl);
            ((SceneManager)sceneControl).hudteste = hud;

            // cria o ponteiro do mouse
            ponteiro = Game.Content.Load<Texture2D>("Textures/HUD/ponteiro");
            ponteiroposition = Vector2.Zero;

            //Cria camera
            camera = new BasicCamera(Game);

            //Controle de cena
            sceneControl.Camera = camera;

            //Cria controle de camera
            cameraControl = new CameraControl(Game, camera, hud);
            sceneControl.CameraControl = cameraControl;

            //Cria cenario
            sceneControl.Stage = new Stage(Game, camera);

            //Cria Mapa de caminho
            pathMap = new PathMap(sceneControl.Stage.Bounds, new Point(10, 10));
            sceneControl.PathMap = pathMap;

            //Atualiza mapa com os objetos do palco
            sceneControl.UpdatePathMap();

            // Cria o turno
            //turn = new Turn();

            //cria controle de caracter
            //sceneControl.CaracterControl = new CharacterControl(this, camera, turn);
            sceneControl.CaracterControl = new CharacterControl(Game, camera);

            //Cria Gerenciador de Inimigos
            e = new EnemiesManager(Game, sceneControl);
            sceneControl.EnemiesManager = e;

            //Cria Gerenciador de turno
            sceneControl.TurnManager = new TurnManager(Game, sceneControl);
            sceneControl.TurnManager.HandlerEndAllPlayersTurn = EndTurn;

            //Cria ceu
            sky = new Sky(Game, camera);

            soldier = new Soldier(Game, camera);
            soldier.BoardPosition = new Point(15, 6);
            soldier.CenterPositionBoardSquare(pathMap);

            soldier.LoadFrom(defaults.Soldier);
            sceneControl.AddCharacter(soldier);
            sceneControl.CaracterControl.CurrentCaracter = soldier;

            ((SceneManager)sceneControl).InitializeTurneManager();

        }

        /// <summary>
        /// final do turno
        /// </summary>
        /// <param name="turnoNumber"></param>
        public void EndTurn(int turnoNumber)
        {
            if (soldier.BoardPosition.X >= 25 && soldier.BoardPosition.Y >= 25)
            {
                endGame = true;
            }
        }

        #endregion
    }
}
